__author__ = 'Muscle'
import weakref

from mui.muicomponent import MUIComponent
from mui.Widgets.muiarrowctrl import MUIArrowController
from mui.Widgets.muibutton import MUIGroupBase

class MUIRegionLayoutItem:
    """ RegionLayoutItem
    """
    keymap = {
        'l':'left',
        't':'top',
        'r':'right',
        'b':'bottom',
        'h':'horz',
        'v':'vert',
        'left':'left',
        'top':'top',
        'right':'right',
        'bottom':'bottom',
        'horz':'horz',
        'vert':'vert'
    }
    def __init__(self, control, parent, dock):
        self.control = weakref.ref(control)

        self.center_horz    = dock.get('horz', False) or dock.get('h', False)
        self.center_vert    = dock.get('vert', False) or dock.get('v', False)
        self.follow_top     = ('top' in dock) or ('t' in dock)
        self.follow_bottom  = ('bottom' in dock) or ('b' in dock)
        self.follow_left    = ('left' in dock) or ('l' in dock)
        self.follow_right   = ('right' in dock) or ('r' in dock)

        for d in dock:
            setattr(self, 'region_' + MUIRegionLayoutItem.keymap[d], dock[d])

        self.sizing(parent)

    def sizing(self, parent):
        control = self.control()
        if not control:
            return

        if self.center_vert:
            height = parent.height
            top = 0
            if self.follow_top:
                height -= self.region_top
                top = self.region_top
            if self.follow_bottom:
                height -= self.region_bottom
            control.top = int( top + (height - control.height) / 2.0 )
        else:
            if self.follow_top and self.follow_bottom:
                control.top = self.region_top
                control.height = parent.height - self.region_top - self.region_bottom
            elif self.follow_top:
                control.top = self.region_top
            elif self.follow_bottom:
                control.top = parent.height - self.region_bottom - control.height

        if self.center_horz:
            width = parent.width
            left = 0
            if self.follow_left:
                width -= self.region_left
                left = self.region_left
            if self.follow_right:
                width -= self.region_right
            control.left = int( left + (width - control.width) / 2.0 )
        else:
            if self.follow_left and self.follow_right:
                control.left = self.region_left
                control.width = parent.width - self.region_left - self.region_right
            elif self.follow_left:
                control.left = self.region_left
            elif self.follow_right:
                control.left = parent.width - self.region_right - control.width

class MUILayoutManager:
    """ MUILayoutManager

    MUILayoutManager must be use in Component, else the bind function will be fail
    """
    def __init__(self):
        self.layout_items = []
        self.autoLayout([], ['Size Change', 'Child Size Change'])
        self.bind('Close', self.clear, noarg = True)

    def autoLayout(self, attributes, events=None):
        if events is None:
            events = []

        for i in attributes:
            self.changeEvent(i, self.recalc, postevent = False)
        for i in events:
            self.bind(i, self.recalc, postevent = False, noarg = True)

    def dock(self, comp, side):
        self.layout_items.append(MUIRegionLayoutItem(comp, self, side))

    def undock(self, comp):
        self.layout_items = filter(lambda x: x.control() != comp, self.layout_items)

    def recalc(self):
        for e in self.layout_items:
            e.sizing(self)

    def clear(self):
        self.layout_items = []

    def setAttachedProperty(self, prop, **argd):
        name = prop['name'].split('.')[-1].lower()
        data = prop['data']
        child = prop['child']
        if name == 'dock':
            docks = data.split(',')
            dock_cmd = {}
            for d in docks:
                dock, region = d.split(':')
                dock = dock.strip().lower()
                try:
                    dock = RegionLayoutItem.keymap[dock]
                except:
                    print '[layout.py] unknown dock name(%s) !!!' % dock
                try:
                    region = region.strip()
                    region = eval(region)
                except:
                    if argd.get('parser', None):
                        region = argd['parser'].queryMacroValue(region)
                    else:
                        region = eval(region, argd['macro'])
                dock_cmd[dock] = region
            self.dock(child, dock_cmd)


#-------------------------------------------------------------------------------
# class Canvas
#-------------------------------------------------------------------------------
class MUICanvas(MUIComponent, MUILayoutManager, MUIArrowController):
    """ MUICanvas
    """
    def __init__(self, parent=None, **argd):
        MUIComponent.__init__(self, parent, **argd)
        MUILayoutManager.__init__(self)
        MUIArrowController.__init__(self)
        self.tabStop = False

    def onKey(self, msgType, key, symbol, modifiers):
        if MUIArrowController.direct(self, msgType, symbol, modifiers):
            return True
        return super(MUICanvas, self).onKey(msgType, key, symbol, modifiers)

    def setAttachedProperty(self, prop, **argd):
        LayoutManager.setAttachedProperty(self, prop, **argd)
        ArrowController.setAttachedProperty(self, prop, **argd)

    def setCommandProperty(self, prop, **keyword):
        super(MUICanvas, self).setCommandProperty(prop, **keyword)
        ArrowController.setCommandProperty(self, prop, **keyword)

class MUIGroupCanvas(MUICanvas, MUIGroupBase):
    """ Group + Canvas
    """
    def __init__(self, parent=None, **argd):
        MUICanvas.__init__(self, parent, **argd)
        MUIGroupBase.__init__(self)
